package com.frame.interceptor;

import com.frame.common.RespEnum;
import com.frame.common.annotation.NeedAuth;
import com.frame.common.constant.ParametersConstants;
import com.frame.common.constant.RedisConstant;
import com.frame.common.enums.LanguageType;
import com.frame.common.exception.AuthException;
import com.frame.common.exception.ServerException;
import com.frame.para.ParametersUtil;
import com.frame.redis.StringRedisUtil;
import com.frame.servlet.HttpServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器的编写
 * @author sunjg
 */
@Slf4j
@Configuration
public class AuthInterceptor extends HandlerInterceptorAdapter {

   @Autowired
   private StringRedisUtil redisUtil;

    /**
     * 对于含有 AuthValidation标签的Controller方法，验证请求里的token和userId。
     * 对于不含 AuthValidation标签的Controller方法，直接放行。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpServletUtil.init(request,response);

        if(request.getMethod().equals("OPTIONS")){
            return true;
        }

        //获取语言
        String lan = request.getHeader(ParametersConstants.LANGUAGE);
        if(!ParametersUtil.isNull(lan)){
            LanguageType languageType = LanguageType.descriptionOf(lan.toUpperCase());
            if(!ParametersUtil.isNull(languageType)) {
                request.setAttribute(ParametersConstants.LANGUAGE, languageType);
            }
        }

        HandlerMethod m = (HandlerMethod) handler;
        NeedAuth needAuth = m.getMethod().getAnnotation(NeedAuth.class);

        if (needAuth == null) {
            return true;
        }

        String token = request.getHeader(ParametersConstants.ACCESS_TOKEN);
        if(token == null){
            throw new ServerException(RespEnum.REQUEST_PARAM_ERROR);
        }
        String userId = redisUtil.get(RedisConstant.USER_ACCESS_TOKEN+token);

        if(userId != null && userId.length()>0){
            request.setAttribute(ParametersConstants.USER_ID,userId);
            return true;
        }else {
            throw new AuthException(RespEnum.USER_AUTHENTICATION);
        }
    }





    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if(log.isInfoEnabled()) {
            log.info("SYS_INFO time:{};ip:{};uri:{};agent:{}",
                    new Object[]{
                            (System.currentTimeMillis() - (Long) request.getAttribute("AUTH_START_TIME")),
                            HttpServletUtil.getRequestIp(request),
                            request.getRequestURI(),
                            request.getHeader("User-agent")
                    }
            );
        }

    }


}
